package com.leyou.utils;


import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 黑马程序员
 */
@Slf4j
public class BeanHelper {

    public static <T> T copyProperties(Object source, Class<T> target) {
        try {
            T t = target.newInstance();
            BeanUtils.copyProperties(source, t);
            return t;
        } catch (Exception e) {
            log.error("【数据转换】数据转换出错，目标对象{}构造函数异常", target.getName(), e);
//            throw new LyException(ExceptionEnum.DATA_TRANSFER_ERROR);
            return null;
        }
    }

    public static <T> List<T> copyWithCollection(List<?> sourceList, Class<T> target) {
        try {
            return sourceList.stream().map(s -> copyProperties(s, target)).collect(Collectors.toList());
        } catch (Exception e) {
            log.error("【数据转换】数据转换出错，目标对象{}构造函数异常", target.getName(), e);
//            throw new LyException(ExceptionEnum.DATA_TRANSFER_ERROR);
            return null;
        }

    }

    public static <T> Set<T> copyWithCollection(Set<?> sourceList, Class<T> target) {
        try {
            return sourceList.stream().map(s -> copyProperties(s, target)).collect(Collectors.toSet());
        } catch (Exception e) {
            log.error("【数据转换】数据转换出错，目标对象{}构造函数异常", target.getName(), e);
//            throw new LyException(ExceptionEnum.DATA_TRANSFER_ERROR);
            return null;
        }
    }


    /**
     * map转成obj
     * 只能对javabean使用
     *
     * @param map
     * @param cls
     * @param <T>
     * @return
     */
    public static <T> T Map2Bean(Map<String, Object> map, Class cls) {
        T instance = null;
        try {
            instance = (T) cls.newInstance();
            while (cls != Object.class) {
                Field[] fields = cls.getDeclaredFields();
                for (Field field : fields) {
                    String name = field.getName();
                    Field type;
                    try {
                        type = cls.getDeclaredField(name);
                        if (type != null) {
                            type.setAccessible(true);
                            Object value = map.get(name);
                            if (value != null) {
                                type.set(instance, value);
                            }
                        }
                    } catch (NoSuchFieldException | IllegalAccessException e1) {
                        e1.printStackTrace();
                    }
                }
                cls = (Class<T>) cls.getSuperclass();
            }
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return instance;
    }


    public static Map<String, Object> Bean2Map(Object e, String[] keys) {
        return Bean2Map(e, false, keys);
    }

    public static Map<String, Object> Bean2Map(Object e, boolean ignoreNullValue, String[] keys) {
        Map<String, Object> map = new HashMap<>();
        List<String> list = Arrays.asList(keys);
        HashSet<String> set = new HashSet<>(list);
        Class<?> cls = e.getClass();
        while (cls != Object.class) {
            Field[] fields = cls.getDeclaredFields(); //每一个字段的值
            for (Field field : fields) {
                String name = field.getName();
                Field type;
                try {
                    if (set.contains(name)) {
                        continue;
                    }
                    type = cls.getDeclaredField(name);
                    if (type != null) {
                        type.setAccessible(true);
                        Object value = type.get(e);
                        if (ignoreNullValue) {
                            if (value != null)
                                map.put(name, value);
                        } else {
                            map.put(name, value);
                        }
                    }
                } catch (NoSuchFieldException | IllegalAccessException e1) {
                    e1.printStackTrace();
                }
            }
            cls = cls.getSuperclass();
        }
        return map;
    }

}
